package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.NormAttribute;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.EmpNormAttribute;
import com.ruoyi.system.domain.EmpNormSystem;
import com.ruoyi.system.mapper.EmpNormAttributeMapper;
import com.ruoyi.system.mapper.EmpNormSystemMapper;
import com.ruoyi.system.service.IEmpNormAttributeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 指标属性Service业务层处理
 *
 * @author zsl
 * @date 2024-04-15
 */
@Service
@Slf4j
public class EmpNormAttributeServiceImpl implements IEmpNormAttributeService {
    @Autowired
    private EmpNormAttributeMapper empNormAttributeMapper;

    @Autowired
    private EmpNormSystemMapper empNormSystemMapper;

    /**
     * 查询指标属性
     *
     * @param id 指标属性主键
     * @return 指标属性
     */
    @Override
    public EmpNormAttribute selectEmpNormAttributeById(Long id) {
        return empNormAttributeMapper.selectEmpNormAttributeById(id);
    }

    /**
     * 查询指标属性列表
     *
     * @param empNormAttribute 指标属性
     * @return 指标属性
     */
    @Override
    public List<EmpNormAttribute> selectEmpNormAttributeList(EmpNormAttribute empNormAttribute) {
        return empNormAttributeMapper.selectEmpNormAttributeList(empNormAttribute);
    }

    /**
     * 新增指标属性
     *
     * @param empNormAttribute 指标属性
     * @return 结果
     */
    @Override
    public int insertEmpNormAttribute(EmpNormAttribute empNormAttribute) {
        empNormAttribute.setCreateTime(DateUtils.getNowDate());
        return empNormAttributeMapper.insertEmpNormAttribute(empNormAttribute);
    }

    /**
     * 修改指标属性
     *
     * @param empNormAttribute 指标属性
     * @return 结果
     */
    @Override
    public int updateEmpNormAttribute(EmpNormAttribute empNormAttribute) {
        if (StringUtils.isEmpty(empNormAttribute.getName()) || ObjectUtils.isEmpty(empNormAttribute.getId())) {
            log.error("指标属性修改失败，属性名称或ID为空");
            return 0;
        }
        empNormAttribute.setUpdateTime(DateUtils.getNowDate());
        int update = empNormAttributeMapper.updateEmpNormAttribute(empNormAttribute);
        if (update == 1) {
            //更新指标体系表的名称
            EmpNormSystem empNormSystem = new EmpNormSystem();
            empNormSystem.setName(empNormAttribute.getName());
            LambdaQueryWrapper<EmpNormSystem> wrapper = Wrappers.lambdaQuery(EmpNormSystem.class).eq(EmpNormSystem::getAttributeId, empNormAttribute.getId());
            empNormSystemMapper.update(empNormSystem, wrapper);
        }
        return update;
    }

    /**
     * 批量删除指标属性
     *
     * @param ids 需要删除的指标属性主键
     * @return 结果
     */
    @Override
    public int deleteEmpNormAttributeByIds(Long[] ids) {
        return empNormAttributeMapper.deleteEmpNormAttributeByIds(ids);
    }

    /**
     * 删除指标属性信息
     *
     * @param id 指标属性主键
     * @return 结果
     */
    @Override
    public int deleteEmpNormAttributeById(Long id) {
        return empNormAttributeMapper.deleteEmpNormAttributeById(id);
    }

    @Override
    public List<TreeSelect> selectAttributeTreeList(EmpNormAttribute attribute) {
        List<EmpNormAttribute> attributes = this.selectEmpNormAttributeList(attribute);

        List<NormAttribute> normAttributesTrees = attributes.stream().map(attr -> {
            NormAttribute normAttribute = new NormAttribute();
            normAttribute.setId(attr.getId());
            normAttribute.setName(attr.getName());
            normAttribute.setParentId(attr.getParentId());
            normAttribute.setLevel(attr.getLevel());
            normAttribute.setType(attr.getType());
            return normAttribute;
        }).collect(Collectors.toList());

        return buildAttributeTreeSelect(normAttributesTrees);
    }

    @Override
    public List<TreeSelect> buildAttributeTreeSelect(List<NormAttribute> attributes) {
        List<NormAttribute> attrTrees = buildAttributeTree(attributes);
        return attrTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public List<NormAttribute> buildAttributeTree(List<NormAttribute> attributes) {
        List<NormAttribute> returnList = new ArrayList<>();
        List<Long> tempList = attributes.stream().map(NormAttribute::getId).collect(Collectors.toList());
        for (NormAttribute attribute : attributes) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(attribute.getParentId())) {
                recursionFn(attributes, attribute);
                returnList.add(attribute);
            }
        }
        if (returnList.isEmpty()) {
            returnList = attributes;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<NormAttribute> list, NormAttribute t) {
        // 得到子节点列表
        List<NormAttribute> childList = getChildList(list, t);
        t.setChildren(childList);
        for (NormAttribute tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<NormAttribute> getChildList(List<NormAttribute> list, NormAttribute t) {
        List<NormAttribute> tlist = new ArrayList<>();
        Iterator<NormAttribute> it = list.iterator();
        while (it.hasNext()) {
            NormAttribute n = it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<NormAttribute> list, NormAttribute t) {
        return getChildList(list, t).size() > 0;
    }

}
